package cn.enited.devtools.apiaggregator.api.utils;

import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Map;
import java.util.Objects;

public interface TripletMap<K, V1, V2> extends Map<K, Tuple<V1, V2>> {

    Collection<V1> firstValues();

    Collection<V2> secondValues();

    Tuple<V1, V2> put(K key, V1 firstValue, V2 secondValue);

    Tuple<V1, V2> putIfAbsent(K key, V1 firstValue, V2 secondValue);

    V1 getValue1(K key);

    V1 getValue1OrDefault(K key, V1 other);

    V2 getValue2(K key);

    V2 getValue2OrDefault(K key, V2 other);

    default void forEach(TripletConsumer<? super K, ? super V1, ? super V2> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, Tuple<V1, V2>> entry : entrySet()) {
            K k;
            V1 v1;
            V2 v2;
            try {
                k = entry.getKey();
                Tuple<V1, V2> v = entry.getValue();
                v1 = v.getItem1();
                v2 = v.getItem2();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v1, v2);
        }
    }
}
